package com.example.backend.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * BigDecimal计算工具类，提供空值安全的加减乘除等运算，统一处理小数位数和舍入模式
 */
public class BigDecimalUtils {

    // 默认保留小数位数
    private static final int DEFAULT_SCALE = 2;
    // 默认舍入模式：四舍五入
    private static final RoundingMode DEFAULT_ROUNDING_MODE = RoundingMode.HALF_UP;

    /**
     * 加法运算，支持两个数相加
     *
     * @param num1 加数1
     * @param num2 加数2
     * @return 两数之和，若任一参数为null则返回0
     */
    public static BigDecimal add(BigDecimal num1, BigDecimal num2) {
        num1 = num1 == null ? BigDecimal.ZERO : num1;
        num2 = num2 == null ? BigDecimal.ZERO : num2;
        return num1.add(num2);
    }

    // 新增：支持int类型的加法
    public static BigDecimal add(BigDecimal num1, int num2) {
        return add(num1, new BigDecimal(num2));
    }

    // 新增：支持long类型的加法
    public static BigDecimal add(BigDecimal num1, long num2) {
        return add(num1, new BigDecimal(num2));
    }

    // 新增：支持double类型的加法（注意精度丢失）
    public static BigDecimal add(BigDecimal num1, double num2) {
        return add(num1, BigDecimal.valueOf(num2));
    }

    /**
     * 减法运算，num1减num2
     *
     * @param num1 被减数
     * @param num2 减数
     * @return 两数之差，若任一参数为null则返回0
     */
    public static BigDecimal subtract(BigDecimal num1, BigDecimal num2) {
        num1 = num1 == null ? BigDecimal.ZERO : num1;
        num2 = num2 == null ? BigDecimal.ZERO : num2;
        return num1.subtract(num2);
    }

    // 新增：支持int类型的减法
    public static BigDecimal subtract(BigDecimal num1, int num2) {
        return subtract(num1, new BigDecimal(num2));
    }

    // 新增：支持long类型的减法
    public static BigDecimal subtract(BigDecimal num1, long num2) {
        return subtract(num1, new BigDecimal(num2));
    }

    // 新增：支持double类型的减法（注意精度丢失）
    public static BigDecimal subtract(BigDecimal num1, double num2) {
        return subtract(num1, BigDecimal.valueOf(num2));
    }

    /**
     * 乘法运算
     *
     * @param num1 乘数1
     * @param num2 乘数2
     * @return 两数之积，若任一参数为null则返回0
     */
    public static BigDecimal multiply(BigDecimal num1, BigDecimal num2) {
        if (num1 == null || num2 == null) {
            return BigDecimal.ZERO;
        }
        return num1.multiply(num2);
    }

    // 新增：支持int类型的乘法
    public static BigDecimal multiply(BigDecimal num1, int num2) {
        return multiply(num1, new BigDecimal(num2));
    }

    // 新增：支持long类型的乘法
    public static BigDecimal multiply(BigDecimal num1, long num2) {
        return multiply(num1, new BigDecimal(num2));
    }

    // 新增：支持double类型的乘法（注意精度丢失）
    public static BigDecimal multiply(BigDecimal num1, double num2) {
        return multiply(num1, BigDecimal.valueOf(num2));
    }

    /**
     * 除法运算，使用默认精度和舍入模式
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return 两数之商，若被除数为null则返回0，若除数为null或0则抛出异常
     * @throws ArithmeticException 当除数为0时抛出
     */
    public static BigDecimal divide(BigDecimal dividend, BigDecimal divisor) {
        return divide(dividend, divisor, DEFAULT_SCALE, DEFAULT_ROUNDING_MODE);
    }

    // 新增：支持int类型的除法
    public static BigDecimal divide(BigDecimal dividend, int divisor) {
        return divide(dividend, new BigDecimal(divisor), DEFAULT_SCALE, DEFAULT_ROUNDING_MODE);
    }

    // 新增：支持long类型的除法
    public static BigDecimal divide(BigDecimal dividend, long divisor) {
        return divide(dividend, new BigDecimal(divisor), DEFAULT_SCALE, DEFAULT_ROUNDING_MODE);
    }

    // 新增：支持double类型的除法（注意精度丢失）
    public static BigDecimal divide(BigDecimal dividend, double divisor) {
        return divide(dividend, BigDecimal.valueOf(divisor), DEFAULT_SCALE, DEFAULT_ROUNDING_MODE);
    }

    /**
     * 除法运算，自定义精度和舍入模式
     *
     * @param dividend     被除数
     * @param divisor      除数
     * @param scale        保留小数位数
     * @param roundingMode 舍入模式
     * @return 两数之商，若被除数为null则返回0，若除数为null或0则抛出异常
     * @throws ArithmeticException 当除数为0时抛出
     */
    public static BigDecimal divide(BigDecimal dividend, BigDecimal divisor, int scale, RoundingMode roundingMode) {
        if (dividend == null) {
            return BigDecimal.ZERO;
        }
        if (divisor == null || divisor.compareTo(BigDecimal.ZERO) == 0) {
            throw new ArithmeticException("除数不能为0");
        }
        return dividend.divide(divisor, scale, roundingMode);
    }

    /**
     * 比较两个数的大小
     *
     * @param num1 数字1
     * @param num2 数字2
     * @return -1（num1<num2），0（num1=num2），1（num1>num2），若参数为null则视为0
     */
    public static int compare(BigDecimal num1, BigDecimal num2) {
        num1 = num1 == null ? BigDecimal.ZERO : num1;
        num2 = num2 == null ? BigDecimal.ZERO : num2;
        return num1.compareTo(num2);
    }

    // 新增：支持int类型的比较
    public static int compare(BigDecimal num1, int num2) {
        return compare(num1, new BigDecimal(num2));
    }

    // 新增：支持long类型的比较
    public static int compare(BigDecimal num1, long num2) {
        return compare(num1, new BigDecimal(num2));
    }

    // 新增：支持double类型的比较（注意精度丢失）
    public static int compare(BigDecimal num1, double num2) {
        return compare(num1, BigDecimal.valueOf(num2));
    }

    /**
     * 保留指定小数位数，使用默认舍入模式
     *
     * @param number 要处理的数字
     * @param scale  保留小数位数
     * @return 处理后的数字，若参数为null则返回0
     */
    public static BigDecimal setScale(BigDecimal number, int scale) {
        return setScale(number, scale, DEFAULT_ROUNDING_MODE);
    }

    /**
     * 保留指定小数位数，自定义舍入模式
     *
     * @param number       要处理的数字
     * @param scale        保留小数位数
     * @param roundingMode 舍入模式
     * @return 处理后的数字，若参数为null则返回0
     */
    public static BigDecimal setScale(BigDecimal number, int scale, RoundingMode roundingMode) {
        if (number == null) {
            return BigDecimal.ZERO;
        }
        return number.setScale(scale, roundingMode);
    }

    /**
     * 判断BigDecimal是否为0
     *
     * @param number 要判断的数字
     * @return true（等于0）或false（不等于0或为null）
     */
    public static boolean isZero(BigDecimal number) {
        return number != null && number.compareTo(BigDecimal.ZERO) == 0;
    }

    /**
     * 判断BigDecimal是否大于0
     *
     * @param number 要判断的数字
     * @return true（大于0）或false（小于等于0或为null）
     */
    public static boolean isPositive(BigDecimal number) {
        return number != null && number.compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * 判断BigDecimal是否小于0
     *
     * @param number 要判断的数字
     * @return true（小于0）或false（大于等于0或为null）
     */
    public static boolean isNegative(BigDecimal number) {
        return number != null && number.compareTo(BigDecimal.ZERO) < 0;
    }

    /**
     * 将对象转换为BigDecimal
     *
     * @param value 要转换的对象（支持String、Number等类型）
     * @return 转换后的BigDecimal，若转换失败或为null则返回null
     */
    public static BigDecimal convertToBigDecimal(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof String) {
            try {
                return new BigDecimal((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        if (value instanceof Number) {
            return new BigDecimal(value.toString());
        }
        try {
            return new BigDecimal(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    public static void main(String[] args) {
        // 使用示例
        BigDecimal num1 = new BigDecimal("10.25");

        System.out.println("与int加法: " + add(num1, 5)); // 15.25
        System.out.println("与long减法: " + subtract(num1, 2L)); // 8.25
        System.out.println("与double乘法: " + multiply(num1, 2.5)); // 25.625
        System.out.println("与int除法: " + divide(num1, 4)); // 2.56
        System.out.println("与double比较: " + compare(num1, 10.5)); // -1
    }
}